/**
 * @Project Name:hoofungson-log-service
 * @Package Name:cn.hoofungson.log.service.util
 * @Since JDK 1.8
 */

package cn.hoofungson.framework.elk.log.util;

import cn.hoofungson.framework.elk.log.constant.config.NetworkCardConstants;
import cn.hoofungson.framework.elk.log.domain.vo.network.NetworkCardVO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.*;
import java.util.regex.Pattern;

/**
 * @Description: 网络工具
 * @Author 胡松 hoofungson@163.com
 * @Date 2019-08-21 14:12
 * @Version V1.0
 */
public class NetworkCardUtils {

    /**
     * 声明日志
     **/
    private static final Logger LOGGER = LoggerFactory.getLogger(NetworkCardUtils.class);

    /**
     * 主机
     **/
    private static String host;

    /**
     * 主机名称
     **/
    private static String hostName;

    /**
     * IPv4地址的正则表达式
     **/
    private static final Pattern IPV4_REGEX = Pattern.compile("^(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}");

    /**
     * IPv6地址的正则表达式
     **/
    private static final Pattern IPV6_STD_REGEX = Pattern.compile("^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}");

    /**
     * 获取网卡名称及IP信息
     **/
    public static Map<String, NetworkCardVO> getNetworkDetailInfo(String netCard) {
        try {
            Map<String, NetworkCardVO> networkCardMap = new HashMap<>();
            Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces();
            while (netInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = netInterfaces.nextElement();
                Enumeration<InetAddress> inetAddress = netInterface.getInetAddresses();
                List<String> ipAddressList = new ArrayList<>();
                while (inetAddress.hasMoreElements()) {
                    InetAddress subInetAddress = inetAddress.nextElement();
                    ipAddressList.add(subInetAddress.getHostAddress());
                }
                NetworkCardVO networkCardVO = new NetworkCardVO();
                networkCardVO.setName(netInterface.getName());
                //取出ip地址列表区分v4和v6
                ipAddressList.forEach(ipAddress -> {
                    if (IPV4_REGEX.matcher(ipAddress).matches()) {
                        networkCardVO.setIpAddressV4(ipAddress);
                    }
                    if (IPV6_STD_REGEX.matcher(ipAddress).matches()) {
                        networkCardVO.setIpAddressV6(ipAddress);
                    }
                });
                networkCardMap.put(networkCardVO.getName(), networkCardVO);
            }
            return networkCardMap;
        } catch (SocketException e) {
            LOGGER.error("获取网卡信息异常：", e);
            return Collections.emptyMap();
        }
    }

    /**
     * 获取主机名称
     *
     * @return
     **/
    protected static String getSystemHostName() {
        try {
            return InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
            e.printStackTrace();
            return StringUtils.EMPTY;
        }
    }

    /**
     * 获取网卡IP信息
     *
     * @return
     **/
    protected static String getIpAddressV4(String netCardName) {
        if (StringUtils.isBlank(netCardName)) {
            netCardName = NetworkCardConstants.DEFAULT_NET_CARD_NAME;
        }
        Map<String, NetworkCardVO> networkCardMap = NetworkCardUtils.getNetworkDetailInfo(netCardName);
        NetworkCardVO networkCardVO = networkCardMap.get(netCardName);
        if (StringUtils.isBlank(networkCardVO.getIpAddressV4())) {
            return "localhost";
        }
        return networkCardVO.getIpAddressV4();
    }

    /**
     * 获取主机IP地址
     *
     * @return
     **/
    public static String getHost(String netCardName) {
        if (StringUtils.isNotBlank(host)) {
            return host;
        }
        if (StringUtils.isBlank(netCardName)) {
            host = getIpAddressV4(netCardName);
        }
        if (StringUtils.isBlank(host)) {
            host = StringUtils.EMPTY;
        }
        return host;
    }

    /**
     * 获取主机名称
     *
     * @return
     **/
    public static String getHostName() {
        if (StringUtils.isNotBlank(hostName)) {
            return hostName;
        }
        if (StringUtils.isBlank(hostName)) {
            hostName = getSystemHostName();
        }
        if (StringUtils.isBlank(hostName)) {
            hostName = StringUtils.EMPTY;
        }
        return hostName;
    }
}
